#ifndef ARRAY_HPP_
#define ARRAY_HPP_

#include "../base/Exception.h"

template <class T>
Array<T>::Array(natural arraySize)
{
	value2   = new T[arraySize];
	offset  = 0;
	count   = arraySize;
	counter = new int;

	*counter = 1;
}

template <class T>
Array<T>::~Array()
{
	unreference();
}

template <class T>
Array<T>::Array(const Array<T>& in)
{
	value2    = in.value2;
	offset   = in.offset;
	count    = in.count;
	counter  = in.counter;
	(*counter)++;
}

template <class T>
void Array<T>::unreference()
{
	(*counter)--;
	if((*counter) == 0)
	{
		delete [] value2;
		delete counter;
	}
}

template <class T>
Array<T> Array<T>::operator=(const Array<T>& in)
{
	unreference();

	value2    = in.value2;
	offset   = in.offset;
	count    = in.count;
	counter  = in.counter;
	(*counter)++;

	return *this;
}

template <class T>
bool Array<T>::equals(Comparable& in)
{
	Array<T>* v = dynamic_cast<Array<T>*>(&in);

	if(v == 0)
	{
		return false;
	}

	Array<T>& inref = (Array<T>&)in;

	if(count != inref.count) return false;

	for(natural i = 0; i < count; i++)
		if(value2[i + offset] != inref.value2[i + inref.offset])
			return false;

	return true;
}

template <class T>
T& Array<T>::operator[](natural i)
{
	if(i >= count)
		throw L"Index out of Bounds";

	return value2[offset + i];
}

#endif
